package webproxy

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"thais/cookie"
	"thais/utils"
	"thais/utils/jwt"
	wl "thais/whitelist"

	"github.com/bugfan/to"
)

/*
*	http中间件
 */
func middleHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		var (
			err  error
			data interface{}
		)
		defer func() {
			if err != nil {
				log.Println("Auth error:", err)
			}
		}()
		// 权限校验
		data, err = gainAuth(r)
		if err != nil {
			w.WriteHeader(http.StatusForbidden)
			return
		}
		authObj, ok := data.(map[string]interface{})
		user := to.String(authObj["User"])
		if !ok || user == "" {
			err = errors.New("Assert error or data is invalid!")
			w.WriteHeader(http.StatusForbidden)
			return
		}
		r.Header.Set(cookie.COOKIE_AUTH_USER, user)
		h.ServeHTTP(w, r)
	})
}
func gainAuth(r *http.Request) (interface{}, error) {
	apiCookie, err := r.Cookie(cookie.COOKIE_NAME_API)
	if err != nil {
		return jwt.VerifyJWT3(r.Header.Get("Authorization"))
	} else {
		return jwt.VerifyJWT3(apiCookie.Value)
	}
}

func genAuth(m interface{}) (string, error) {
	return jwt.GetJWT3(m)
}

/*
*	白名单相关rest api
 */
func callback(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		return
	}
	user := r.Header.Get(cookie.COOKIE_AUTH_USER)
	if user == "" {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	list, err := wl.GetList(user)
	if err != nil {
		list = []string{"*"} //异常给*
	}
	callFunc := r.URL.Query().Get("callback")
	fmt.Fprintf(w, callFunc+`(`+utils.ToJsonString(list)+`)`)
}

func list(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodGet {
		get(w, r)
	} else if r.Method == http.MethodPut {
		update(w, r)
	}
	return
}

func get(w http.ResponseWriter, r *http.Request) {
	user := r.Header.Get(cookie.COOKIE_AUTH_USER)
	if user == "" {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	data, err := wl.GetAllRedisMapper()
	if err != nil {
		w.Write([]byte(`{"status":201","msg":"` + to.String(err) + `"}`))
		return
	}
	w.Write([]byte(`{"status":"200","data":"` + utils.ToJsonString(data) + `"}`))
}

func update(w http.ResponseWriter, r *http.Request) {
	user := r.Header.Get(cookie.COOKIE_AUTH_USER)
	if user == "" {
		w.WriteHeader(http.StatusForbidden)
		return
	}
	bs, _ := ioutil.ReadAll(r.Body)
	post := wl.PostHostMap{}
	err := json.Unmarshal(bs, &post)
	if err != nil {
		w.Write([]byte(`{"status":201","msg":"` + to.String(err) + `"}`))
		return
	}
	key, err := wl.NewRedisMapper(&post)
	if err != nil {
		w.Write([]byte(`{"status":201","msg":"` + to.String(err) + `"}`))
		return
	}
	w.Write([]byte(`{"status":200","data":"` + key + `","msg":"success"}`))
}

/*
*	权限相关rest api
 */
func login(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		return
	}
	body, _ := ioutil.ReadAll(r.Body)
	u := map[string]string{}
	err := json.Unmarshal(body, &u)
	if err != nil {
		w.WriteHeader(401)
		return
	}
	user := u["User"] // ruby端登录成功只需要传来用户名就行了
	if user == "" {
		w.WriteHeader(401)
		return
	}
	loginTail(w, u, user)
}
func loginTail(w http.ResponseWriter, data interface{}, key string) {
	cookie := cookie.NewApiCookie(data)
	http.SetCookie(w, cookie)
	w.Write([]byte(`{"cookie":` + cookie.Value + `}`))
	utils.Zlog(utils.LogLevelInfo, "----> New request", "", fmt.Sprintf("Generate Token OK: %s", key))
}
func testLogin(w http.ResponseWriter, r *http.Request) {
	user := "test"
	key := "http_map|test"
	u := map[string]string{
		"User": user,
		"Key":  key,
	}
	loginTail(w, u, user)
}
